﻿/*	Над этими иероглифами располагалась фигура, которая явно была плодом фантазии художника, хотя      */
/*	импрессионистская манера исполнения мешала точно определить ее природу. Это было некое чудовище,   */
/*	или символ, представляющий чудовище, или просто нечто рожденное больным воображением.              */
/*	                    																			   */
/*																						Г.Ф. Лавкрафт  */
package Core
{	
	import com.junkbyte.console.Cc;
	import com.junkbyte.console.Console;
	import com.junkbyte.console.ConsoleChannel;	

	import social.VKontakte.VKProvider;
	import social.VKontakte.VKEvents;	
	
	import MySQL.MySQLProvider;
	
	import Interface.PageWelcome;
	import Interface.PageShop;
	import Interface.PageTracks;
	import Interface.PagesInterface;
	import Interface.PageProfile;
	import Interface.PageBattles;
	import Interface.PageTop100;
	import Interface.PageStatistic;
	import Interface.PageBattleStart;	
	import Interface.UpMenu;
	import Interface.PageMessages;

	import Interface.MessagesClasses.YesNoMessage;
	import Interface.MessagesClasses.ErrorMessage;
	import Interface.MessagesClasses.InfoMessage;
	import Interface.MessagesClasses.TransferMessage;
	import Interface.MessagesClasses.TrackLoadingMessage;
	
	import Gameplay.PageGame;

	import GameUtils.XMLLoader;
	import GameUtils.GameDataEvent;
	import GameUtils.TrackData;
	import GameUtils.UserLoader;
	
	import flash.display.MovieClip;
	import flash.events.Event;	
	import flash.system.Security;		
	import flash.display.DisplayObject;			
	import flash.filters.BlurFilter;	
	import flash.events.MouseEvent;		
	
	public class Game extends MovieClip
	{		
		//Settings, needs to be loaded from server
		private var FSettings:GameSettings;
		//XML
		private var FXMLLoader:XMLLoader;		
		//Social
		private var FProvider:VKProvider;
		//Database provider
		private var FMySQLProvider:MySQLProvider;
		//Multiplayer server's client
		private var FClient:TCPGameClient;	
		//Game connection sequence descriptor
		private var FConnector:GameConnector;
		private var FPlayer:PlayerInfo;
		private var FUsersLoader:UserLoader;
		private var FPreloader:GamePreloader;
		//Pages
		private var FGameplay:PageGame;
		//interface Pages
		private var FInterface:PagesInterface;
		private var FBlock:PageBlock;
		private var FWelcome:PageWelcome;
		private var FShopPage:PageShop;
		private var FTracksPage:PageTracks;
		private var FProfilePage:PageProfile;
		private var FBattlesPage:PageBattles;
		private var FTop100Page:PageTop100;
		private var FStatisticPage:PageStatistic;
		private var FBattleStartPage:PageBattleStart;
		private var FMessages:PageMessages;
		//Effect for pages blur
		private var FBlur:BlurFilter;
		//Pages storage
		private var FPages:Vector.<Page>;
		//Current and previous page
		private var FCurrentPage:Page;		
		private var FPreviousPage:Page;
		
		public function Game():void
		{
			FPlayer = new PlayerInfo();
			
			FXMLLoader = new XMLLoader();
			FXMLLoader.addEventListener(FXMLLoader.ALL_XMLS_LOADED, OnXMLsLoaded);
			
			FClient = new TCPGameClient(this);
			FClient.addEventListener(Event.CONNECT, OnTCPConnect);
			FClient.addEventListener(Event.CLOSE, OnTCPDisconnect);
			
			FConnector = new GameConnector(this);
			
			SetupSecurity();
			SetupInterface();
					
			addEventListener(Event.ADDED_TO_STAGE, OnInit);
		}
		
		private function SetupSecurity():void
		{
			Security.loadPolicyFile('http://vkontakte.ru/crossdomain.xml');
			Security.loadPolicyFile('http://vk.com/crossdomain.xml');
			Security.loadPolicyFile('http://62.212.69.47/crossdomain.xml');
		}				
		
		private function SetupInterface():void
		{
			FPages = new Vector.<Page>;
			FPreloader = getChildByName('PreloaderBar') as GamePreloader;
			//Getting pages					
			FInterface = AddPage('InterfacePages') as PagesInterface;
			FBlock = AddPage('Block') as PageBlock;
			FWelcome = AddPage('WelcomePage', FInterface) as PageWelcome;
			FProfilePage = AddPage('ProfilePage', FInterface) as PageProfile;
			FShopPage = AddPage('ShopPage', FInterface) as PageShop;			
			FTracksPage = AddPage('TracksPage', FInterface) as PageTracks;
			FBattlesPage = AddPage('BattlesPage', FInterface) as PageBattles;
			FTop100Page = AddPage('Top100Page', FInterface) as PageTop100;
			FGameplay = AddPage('GamePage') as PageGame;
			FStatisticPage = AddPage('StatisticPage') as PageStatistic;
			FBattleStartPage = AddPage('BattleStartPage') as PageBattleStart;
			FMessages = getChildByName('MessagesPage') as PageMessages;
			FMessages.visible = false;
			FMessages.GameCore = this;
			//Setting names for pages that will be showed in menus
			FProfilePage.MenuName = 'ПРОФИЛЬ';
			FShopPage.MenuName = 'МАГАЗИН';
			FTracksPage.MenuName = 'МОИ ТРЕКИ';	
			FBattlesPage.MenuName = 'БИТВЫ';	
			FTop100Page.MenuName = 'ТОП 100';
			//Filling Welcome page's menu with pages names			
			FInterface.FillMenu();
			//Setting welcome page as current
			CurrentPage = FWelcome;
			//Filter used for main window's blur while showing messages
			FBlur = new BlurFilter(10,10,2);			
		}
		
		private function AddPage(AName:String, AParent:MovieClip = null):Page
		{
			var vPage:Page;
			if (AParent)
				vPage = Page(AParent.getChildByName(AName));
			else
				vPage = Page(getChildByName(AName));
			vPage.GameCore = this;
			FPages.push(vPage);
			return vPage;
		}
		
		public function set CurrentPage(APage:Page):void
		{
			UnBlockInterface();
			FPreviousPage = FCurrentPage;
			FCurrentPage = APage;
			
			for(var i in FPages)		 				
				FPages[i].visible = false;			
			
			if(FCurrentPage is InterfacePage)
			{
				FInterface.visible = true;				
				FInterface.CurrentPage = FCurrentPage as InterfacePage;
			}
			else
			{
				FCurrentPage.visible = true;
			}
		}
		
		public function get Preloader():GamePreloader
		{
			return FPreloader;
		}
		
		public function get PreviousPage():Page
		{
			return FPreviousPage;
		}
		
		public function get Pages():Vector.<Page>
		{
			return FPages;
		}
		
		public function get Settings():GameSettings
		{			
			return FSettings;
		}
		
		public function set Settings(ASettings: GameSettings):void
		{
			FSettings = ASettings;			
		}
		
		public function get Provider():VKProvider
		{
			return FProvider;
		}
		
		public function set Provider(AProvider: VKProvider):void
		{
			FProvider = AProvider;
		}
		
		public function get TracksLoader():XMLLoader
		{
			return FXMLLoader;
		}
		
		public function get MultiplayerClient():TCPGameClient
		{
			return FClient;
		}
		
		public function get MySQL():MySQLProvider
		{
			return FMySQLProvider;
		}
		
		public function set MySQL(AMySQL:MySQLProvider):void
		{
			FMySQLProvider = AMySQL;
		}
		
		public function get UsersLoader():UserLoader
		{
			return FUsersLoader;
		}
		
		public function set UsersLoader(AUsersLoader:UserLoader):void
		{
			FUsersLoader = AUsersLoader;
		}
		
		public function get Battles():PageBattles
		{
			return FBattlesPage;
		}
		
		public function get Tracks():PageTracks
		{
			return FTracksPage;
		}
		
		public function get Profile():PageProfile
		{
			return FProfilePage;
		}
		
		public function get Shop():PageShop
		{
			return FShopPage;
		}
		
		public function get Interface():PagesInterface
		{
			return FInterface;
		}
		
		public function get InterfaceMenu():UpMenu
		{
			return FInterface.InterfaceMenu;
		}
		
		public function get Statistic():PageStatistic
		{
			return FStatisticPage;
		}
		
		public function get Top100():PageTop100
		{
			return FTop100Page;
		}
				
		public function get Gameplay():PageGame
		{
			return FGameplay;
		}
		
		public function get BattlesStart():PageBattleStart
		{
			return FBattleStartPage;
		}
		
		public function BlockInterface(ABlack:Boolean = true):void
		{
			FBlock.visible = true;
			if(!ABlack)
				FBlock.alpha = 0;
			else
				FBlock.alpha = 0.5;
		}
		
		public function UnBlockInterface():void
		{
			FBlock.alpha = 0.5;
			FBlock.visible = false;
		}
		
		public function get UserID():String
		{
			if (FProvider)
				return FProvider.UserID;
			else
				return '-1';
		}
		
		public function get User():PlayerInfo
		{
			return FPlayer;
		}
		
		public function UpdateProfile():void
		{
			InterfaceMenu.Rating = User.Rating;
			InterfaceMenu.Money = User.Money.toString();
			FProfilePage.Update();
			FMySQLProvider.UpdateProfile(User);
		}
		
		private function OnInit(e:Event):void
		{			
			FConnector.Start();
		}
		
		public function LoadTracksData():void
		{
			FXMLLoader.Load();
		}
		
		private function OnXMLsLoaded(e:GameDataEvent):void
		{			
			FTracksPage.Data = e.Data;			
		}
		
		private function OnTCPConnect(e:Event):void
		{			
			Cc.log('TCP Connected');
			FPreloader.Percent = 1;
			FPreloader.visible = false;
			FWelcome.ShowMenu();
		}
		
		private function OnTCPDisconnect(e:Event):void
		{			
			Cc.log('TCP Disonnected');
		}
		
		public function Blur():void
		{
			if(FCurrentPage)
			{
				BlockInterface();	
			
				if(FCurrentPage is InterfacePage)
				{
					FInterface.filters = [FBlur];					
				}
				else
				{
					FCurrentPage.filters = [FBlur];
				}				
			}			
		}
		
		public function UnBlur():void
		{
			if(FCurrentPage)
			{
				UnBlockInterface();
				if(FCurrentPage is InterfacePage)
				{
					FInterface.filters = [];					
				}
				else
				{
					FCurrentPage.filters = [];
				}	
			}			
		}
		
		public function ShowError(AText:String):ErrorMessage
		{
			Blur();			
			return FMessages.ShowError(AText);
		}
		
		public function ShowInfo(AText:String, AHeaderText:String = '', AButtonText:String = 'OK'):InfoMessage
		{
			Blur();
			var vMessage:InfoMessage = FMessages.ShowInfo(AText, AHeaderText, AButtonText);
			vMessage.OKButton.addEventListener(MouseEvent.MOUSE_DOWN, HideMessage);
			return vMessage;
		}
		
		public function ShowYesNo(AText:String, AHeaderText:String = 'СООБЩЕНИЕ'):YesNoMessage
		{
			Blur();
			var vMessage:YesNoMessage = FMessages.ShowYesNo(AText, AHeaderText)			
			vMessage.NoButton.addEventListener(MouseEvent.MOUSE_DOWN, HideMessage);
			return vMessage;
		}
		
		public function ShowTransferMessage(e:MouseEvent = null)
		{
			Blur();
			var vMessage:TransferMessage = FMessages.ShowTransfer();
			vMessage.CancelButton.addEventListener(MouseEvent.MOUSE_DOWN, HideMessage);
		}
		
		public function ShowTrackLoading(ATrack:TrackData):TrackLoadingMessage
		{
			Blur();
			var vMessage:TrackLoadingMessage = FMessages.ShowTrackLoading(ATrack)			
			vMessage.NoButton.addEventListener(MouseEvent.MOUSE_DOWN, HideMessage);
			return vMessage;
		}
		
		public function HideMessage(e:MouseEvent = null):void
		{			
			FMessages.visible = false;
			UnBlur();
		}
		
		//==================================================== GAMEPLAY ==================================================== //
			
		public function StartTraining(AData:TrackData):void
		{
			FBattleStartPage.addEventListener(FBattleStartPage.COUNT_ENDED, OnCountEnded);
			FBattleStartPage.Enemy = '';			
			
			function OnCountEnded(e:GameDataEvent):void
			{
				CurrentPage = FGameplay;
				FGameplay.Sound = AData;
				FGameplay.Player = User;
				FStatisticPage.Mode = FGameplay.TRAINING;
				FStatisticPage.Enemy = null;				
				FGameplay.Play();				
				FBattleStartPage.removeEventListener(FBattleStartPage.COUNT_ENDED, OnCountEnded);
			}
		}
		
		public function StartBattle(ATrackID:int, AUID:String):void
		{			
			FBattleStartPage.addEventListener(FBattleStartPage.COUNT_ENDED, OnCountEnded);
			FBattleStartPage.Enemy = AUID;
			
			function OnCountEnded(e:GameDataEvent):void
			{
				var vEnemyInfo:PlayerInfo = PlayerInfo(e.Data);			
				var vTrack:TrackData = Tracks.TrackByID(ATrackID);
				FGameplay.Sound = vTrack;
				CurrentPage = FGameplay;			
				FGameplay.Player = User;					
				FStatisticPage.Mode = FGameplay.MULTIPLAYER;
				FStatisticPage.Enemy = vEnemyInfo;				
				FGameplay.Enemy = vEnemyInfo;				
				FGameplay.Play(FGameplay.MULTIPLAYER);
				Cc.log('Initializing multiplayer. Enemy info loaded: ' + vEnemyInfo.Name);
				FBattleStartPage.removeEventListener(FBattleStartPage.COUNT_ENDED, OnCountEnded);
			}
		}
		
		public function StartBotBattle(AUID:String, ATrack:TrackData):void
		{
			FBattleStartPage.addEventListener(FBattleStartPage.COUNT_ENDED, OnCountEnded);
			FBattleStartPage.Enemy = '';
			
			function OnCountEnded(e:GameDataEvent):void
			{
				var vEnemyInfo:PlayerInfo = new PlayerInfo();
				vEnemyInfo.Name = 'Бот';
				vEnemyInfo.Rating =(int(User.Rating) + Math.floor(Math.random() * 200)).toString();
				vEnemyInfo.Photo = '';
				FGameplay.Sound = ATrack;
				CurrentPage = FGameplay;				
				FGameplay.Player = User;
				FGameplay.Enemy = vEnemyInfo;
				FStatisticPage.Mode = FGameplay.BOT;
				FStatisticPage.Enemy = vEnemyInfo;				
				FGameplay.Play(FGameplay.BOT);				
				FBattleStartPage.removeEventListener(FBattleStartPage.COUNT_ENDED, OnCountEnded);
			}
		}
	}	
}
